package com.demo.controller;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.text.CharSequenceUtil;
import com.demo.pojo.UserTest;
import com.demo.service.DemoDllService;
import com.demo.structure.UserStruct;
import com.demo.utils.CommonUtil;
import com.sun.jna.Memory;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.ptr.IntByReference;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.log4j.Log4j2;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

@Log4j2
@RestController
@RequestMapping(("/v1/test"))
@Tag(name = "测试")
public class TestController {

    @GetMapping("/hello")
    public void helloWord(){
        DemoDllService.lib.hello();
        DemoDllService.lib.getNet();
    }

    @GetMapping("/sum_array")
    public int sumArrayTest() {
        int[] data = new int[10];
        for (int i = 0; i < 10; i++) {
            data[i] = 1;
        }
        int res = DemoDllService.lib.sum_array(data, 10);
        log.info(res);
        return res;
    }

    @GetMapping("/create_user")
    public UserTest createUserTest() {
        UserStruct userStruct = new UserStruct();
        userStruct.setId(0).setHigh(1.60).setTimestamp(123456789);
        /*
        byte[] name = "文".getBytes();
        byte[] mark = "kv.".getBytes();
        ArrayUtil.copy(name, 0, user.name, 0, Math.min(name.length, user.name.length));
        ArrayUtil.copy(mark, 0, user.mark, 0, Math.min(mark.length, user.mark.length));
        */
        userStruct.setId(0).setHigh(1.7).setTimestamp(DateUtil.current())
                .setName(Arrays.copyOf("文".getBytes(), UserStruct.NAME_LEN)).setMark(Arrays.copyOf("kv.".getBytes(), UserStruct.MARK_LEN));
        DemoDllService.lib.creatUser(userStruct);
        return new UserTest().setId(userStruct.id).setName(CommonUtil.utf8Str(userStruct.getName()))
                .setHigh(userStruct.high).setTimestamp(userStruct.timestamp)
                .setMark(CommonUtil.utf8Str(userStruct.getMark()));
    }

    @GetMapping("/create_user/ptr")
    public UserTest createUserPtrTest() {
        UserStruct.ByReference userRef = new UserStruct.ByReference();
        userRef.setName(Arrays.copyOf("文".getBytes(), UserStruct.NAME_LEN));
        userRef.setMark(Arrays.copyOf("kv.".getBytes(), UserStruct.MARK_LEN));
        userRef.setId(0).setHigh(1.7).setTimestamp(DateUtil.current());
        DemoDllService.lib.creatUserPointer(userRef, CharSequenceUtil.utf8Bytes("0012Vince\0"));
        UserTest userTest = new UserTest().setId(userRef.id).setName(CommonUtil.utf8Str(userRef.getName()))
                .setHigh(userRef.high).setTimestamp(userRef.timestamp)
                .setMark(CommonUtil.utf8Str(userRef.getMark()));
        userRef.clear();
        return userTest;
    }

    @GetMapping("/getPath")
    public List<String> getPathTest() {
        int size = 3;
        IntByReference num = new IntByReference(size);
        Pointer mark[] = new Pointer[size];
        for (int i = 0; i < size; i++) {
            mark[i] = new Memory(255); // 假设每个路径的最大长度为255
        }
        DemoDllService.lib.getFilePath(mark, num);
        ArrayList<String> res = new ArrayList<>();
        for (int i = 0; i < num.getValue(); i++) {
            String path = mark[i].getString(0);
            res.add(path);
        }
        return res;
    }

    @GetMapping("/user/list")
    public List<UserTest> getUserListTest() {
        int size = 3;
        UserStruct.ByReference[] userStructsRef = (UserStruct.ByReference[]) new UserStruct.ByReference().toArray(size);
        IntByReference intByReference = new IntByReference(size);
        int res = DemoDllService.lib.getUserList(userStructsRef, intByReference);
        log.info(res);
        ArrayList<UserTest> arrayList = new ArrayList<>();
        for (int i = 0; i < intByReference.getValue(); i++) {
            UserTest userTest = new UserTest();
            userTest.setId(userStructsRef[i].id)
                    .setName(CommonUtil.utf8Str(userStructsRef[i].name))
                    .setHigh(userStructsRef[i].high)
                    .setTimestamp(userStructsRef[i].timestamp)
                    .setMark(CommonUtil.utf8Str(userStructsRef[i].mark));
            arrayList.add(userTest);
        }
        return arrayList;
    }

    @GetMapping("/reset/rfi")
    public String getRestRfiTest() {
        // 初始化数组并分配连续的内存空间readDataPathArr
        int size = 2;
        Memory rfiMemory = new Memory((long) size * Native.getNativeSize(Double.TYPE));
        // 设置初始值
        rfiMemory.setDouble(0, 0.0);
        rfiMemory.setDouble(Native.getNativeSize(Double.TYPE), 0.0);
        DemoDllService.lib.resetRfi(rfiMemory);
        // 读取修改后的值
        double rfi0 = rfiMemory.getDouble(0);
        double rfi1 = rfiMemory.getDouble(Native.getNativeSize(Double.TYPE));
        log.info(rfi0);
        log.info(rfi1);
        return "ok";
    }

    @GetMapping("/read/arr")
    public String getReadArrTest() {
        // 创建字符串数组并分配内存
        int size = 3; // 假设数组大小为 3
        Pointer[] dataPath = new Pointer[size];
        // 初始化字符串数组
        for (int i = 0; i < size; i++) {
            dataPath[i] = new Memory(255); // 255 是字符串的最大长度
            dataPath[i].setString(0, "path" + (i + 1)); // 设置每个路径
        }
        DemoDllService.lib.readDataPathArr(dataPath, size);
        return "ok";
    }
}
